home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / cimb.arj / ESCALA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-31  |  8.0 KB  |  322 lines

  1. /*==============================================================================
  2.  
  3. FICHERO: ESCALA.C
  4.  
  5. AUTOR: ANTONIO LADESA JURADO
  6.  
  7. FECHA: 24/6/94
  8.  
  9. DESCRIPCION:
  10.  
  11.     Fichero que contiene las estructuras, constantes, variables y funciones
  12.     internas y externas para el escalado de imágenes.
  13.  
  14. ==============================================================================*/
  15.  
  16.  
  17. /*---- MODULOS USADOS --------------------------------------------------------*/
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <alloc.h>
  22.  
  23. #include "global.h"
  24. #include "memoria.h"
  25. #include "video.h"
  26. #include "escala.h"
  27. #include "error.h"
  28.  
  29.  
  30. /*---- DEFINICION DE LAS FUNCIONES INTERNAS ----------------------------------*/
  31.  
  32. char *EscalarLinea(char *linea,int ancho,double factor);
  33.  
  34. /*---- CODIFICACION DE LAS FUNCIONES OFRECIDAS -------------------------------*/
  35.  
  36.  
  37. /*---- FUNCION: extern IMAGEN *IMAGENescalar(IMAGEN *c,            -------------
  38.                                                                                         double factorx,
  39.                                                                                         double factor y)
  40.  
  41.     Descripción:
  42.  
  43.         Esta función escala una imagen usando factores de ancho y alto.
  44.  
  45.     Parámetros:
  46.  
  47.         IMAGEN *c : puntero a estructura que alberga la imagen.
  48.         double factorx : factor de escala a lo ancho.
  49.         double factory : factor de escala a lo alto.
  50.  
  51.     Retorno:
  52.  
  53.         Si se escala, puntero a la nueva imagen.
  54.         Si no, puntero a la imagen original.
  55.  
  56. ---- CODIGO: -----------------------------------------------------------------*/
  57.  
  58. extern IMAGEN *IMAGENescalar(IMAGEN *c, double factorx,double factory)
  59. {
  60.     /* buffers para las líneas */
  61. char buffer[ANCHO_MAXIMO];
  62. char bufferVGA[ANCHO_MAXIMO];
  63.     /* puntero a nueva imagen */
  64. IMAGEN *e = NULL;
  65.     /* contadores de línea */
  66. int i,j,iant,jant;
  67.  
  68.     /* si no existe imagen */
  69. if(c == NULL)
  70.     {
  71.     ERRORponer(ERRnoImagen);
  72.     return(c);
  73.     }
  74.      /* reservar memoria para la cabecera de trabajo */
  75. if((e=MEMreservarCAB(e))==NULL)
  76.     {
  77.     ERRORponer(ERRnoMemoria);
  78.     return(c);
  79.     }
  80.     /* calcular dimensiones de la nueva imagen */
  81. factorx /= 100.0;
  82. factory /= 100.0;
  83. e->ancho =(double)(c->ancho)*factorx;
  84. e->alto = (double)(c->alto)*factory;
  85.     /* ajustar anchos */
  86. switch(c->modo)
  87.     {
  88.     case VIDEOmono:
  89.         if(e->ancho%2) e->ancho++;
  90.         e->bytes = DePixelsABytes(e->ancho);
  91.         if(e->bytes%2) e->bytes++;
  92.     break;
  93.     case VIDEOega:
  94.             /* el ancho debe ser mútiplo de 8 */
  95.         if(e->ancho%8)
  96.             e->ancho+=(8 - (e->ancho%8));
  97.         e->bytes = DePixelsABytes(e->ancho)*4;
  98.     break;
  99.     case VIDEOvga:
  100.             /* número par de pixels */
  101.         if(e->ancho%2) e->ancho++;
  102.         e->bytes = e->ancho;
  103.     break;
  104.     }
  105.     /* si la imagen resultante es muy grande o muy pequeña */
  106. if(e->ancho > ANCHO_MAXIMO || e->ancho < 16 || e->alto < 16 )
  107.     {
  108.     ERRORponer(ERRescalar);
  109.     e = MEMliberar(e);
  110.     return(c);
  111.     }
  112.     /* reservar memoria para la imagen */
  113. if(!MEMreservar(e))
  114.     {
  115.     e =MEMliberar(e);
  116.     ERRORponer(ERRnoMemoria);
  117.     return(c);
  118.     }
  119.     /* cargar cabecera de trabajo */
  120. if(c->haypaleta)
  121.     memcpy(e->paleta,c->paleta,c->colores*3);
  122. strcpy(e->nombre,c->nombre);
  123. e->formato = c->formato;
  124. e->modo = c->modo;
  125. e->colores = c->colores;
  126. e->haypaleta = c->haypaleta;
  127.  
  128.     /* escalar segun el modo de video */
  129. switch(c->modo)
  130.     {
  131.   case VIDEOmono:
  132.             /* si es una reducción */
  133.         if(c->alto > e->alto)
  134.             for(i=0,jant=1;i<c->alto;++i)
  135.                 {
  136.                     /* calcular línea destino */
  137.                 j = (double)i*factory;
  138.                     /* si no es la anterior, reducirla y llevarla a memoria */
  139.                 if(j != jant)
  140.                     {
  141.                         /* leer linea */
  142.                     MEMleer(buffer,i,c);
  143.                         /* convertir a VGA para escalar */
  144.                     MONOaVGA(buffer,bufferVGA,c->ancho);
  145.                         /* escalar */
  146.                     memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
  147.                         /* convertir a monocroma */
  148.                     VGAaMONO(bufferVGA,buffer,e->ancho);
  149.                         /* escribir linea */
  150.                     MEMescribir(buffer,j,e);
  151.                         /* actualizar línea anterior */
  152.                     jant = j;
  153.                     }
  154.                 }
  155.             /* si es una ampliación */
  156.         else
  157.             for(j=0,iant=1;j<e->alto;++j)
  158.                 {
  159.                     /* calcular la línea de origen */
  160.                 i=(double)j/factory;
  161.                     /* si no es la misma de antes, ampliarla */
  162.                 if(i!=iant)
  163.                     {
  164.                         /* leer linea */
  165.                     MEMleer(buffer,i,c);
  166.                         /* convertir a VGA para escalarla */
  167.                     MONOaVGA(buffer,bufferVGA,c->ancho);
  168.                         /* escalar */
  169.                     memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
  170.                         /* convertir a MONO */
  171.                     VGAaMONO(bufferVGA,buffer,e->ancho);
  172.                     }
  173.                     /* escribir linea en memoria */
  174.                 MEMescribir(buffer,j,e);
  175.                     /* actualizar línea anterior */
  176.                 iant = i;
  177.                 }
  178.     break;
  179.  
  180.     case VIDEOega:
  181.             /* si es una reducción */
  182.         if(c->alto > e->alto)
  183.             for(i=0,jant=1;i<c->alto;++i)
  184.                 {
  185.                     /* calcular línea destino */
  186.                 j = (double)i*factory;
  187.                     /* si no es la anterior, reducirla y llevarla a memoria */
  188.                 if(j != jant)
  189.                     {
  190.                         /* leer linea */
  191.                     MEMleer(buffer,i,c);
  192.                         /* convertir a VGA para escalarla */
  193.                     EGAaVGA(buffer,bufferVGA,c->ancho);
  194.                         /* escalar */
  195.                     memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
  196.                         /* convertir a EGA */
  197.                     VGAaEGA(bufferVGA,buffer,e->ancho);
  198.                         /* escribir linea en memoria */
  199.                     MEMescribir(buffer,j,e);
  200.                     jant = j;
  201.                     }
  202.                 }
  203.         else
  204.             /* si es una ampliación */
  205.             for(j=0,iant=1;j<e->alto;++j)
  206.                 {
  207.                     /* calcular línea origen */
  208.                 i=(double)j/factory;
  209.                     /* si no es la anterior, ampliarla */
  210.                 if(i!=iant)
  211.                     {
  212.                         /* leer linea */
  213.                     MEMleer(buffer,i,c);
  214.                         /* convertir a VGA */
  215.                     EGAaVGA(buffer,bufferVGA,c->ancho);
  216.                         /* escalar */
  217.                     memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
  218.                         /* convertir a EGA */
  219.                     VGAaEGA(bufferVGA,buffer,e->ancho);
  220.                     }
  221.                     /* escribir linea en memoria */
  222.                 MEMescribir(buffer,j,e);
  223.                 }
  224.     break;
  225.  
  226.     case VIDEOvga:
  227.             /* si es una reducción */
  228.         if(c->alto > e->alto)
  229.             for(i=0,jant = 1;i<c->alto;++i)
  230.                 {
  231.                     /* calcular línea destino */
  232.                 j = (double)i*factory;
  233.                     /* si no es la misma de antes, reducirla y llevarla a memoria */
  234.                 if(j!=jant)
  235.                     {
  236.                         /* leer línea */
  237.                     MEMleer(bufferVGA,i,c);
  238.                         /* escalar */
  239.                     memcpy(bufferVGA,EscalarLinea(bufferVGA,c->ancho,factorx),e->ancho);
  240.                         /* escribir línea en memoria */
  241.                     MEMescribir(bufferVGA,j,e);
  242.                     jant = j;
  243.                     }
  244.                 }
  245.         else
  246.                 /* si es una ampliación */
  247.             for(j=0,iant=1;j<e->alto;++j)
  248.                 {
  249.                     /* calcular línea origen */
  250.                 i=(double)j/factory;
  251.                     /* si no es la misma de antes, ampliarla */
  252.                 if(i!=iant)
  253.                     {
  254.                         /* leer linea */
  255.                     MEMleer(buffer,i,c);
  256.                         /* escalar */
  257.                     memcpy(bufferVGA,EscalarLinea(buffer,c->ancho,factorx),e->ancho);
  258.                     }
  259.                     /* escribir linea en memoria */
  260.                 MEMescribir(bufferVGA,j,e);
  261.                 iant = i;
  262.                 }
  263.     break;
  264.     }
  265.     /* devolver nueva imagen escalada */
  266. c = MEMliberar(c);
  267. c = NULL;
  268. return(e);
  269. }
  270.  
  271. /*---- FIN FUNCION -----------------------------------------------------------*/
  272.  
  273.  
  274. /*---- CODIFICACION DE LAS FUNCIONES INTERNAS --------------------------------*/
  275.  
  276.  
  277. /*---- FUNCION: char *EscalarLinea(char *linea,int ancho,double factor ---------
  278.  
  279.     Descripción:
  280.  
  281.         Esta función amplía o reduce una línea (en formato VGA), usando un factor
  282.         de escala.
  283.  
  284.     Parámetros:
  285.  
  286.         char *linea : puntero a la línea a escalar.
  287.         int ancho : ancho de la línea antes de escalarla.
  288.         double factor: factor de escalado.
  289.  
  290.     Retorno:
  291.  
  292.         Puntero a la línea escalada.
  293.  
  294. ---- CODIGO: -----------------------------------------------------------------*/
  295.  
  296. char *EscalarLinea(char *linea,int ancho,double factor)
  297. {
  298.     /* contador de líneas */
  299. int i;
  300.     /* ancho para ampliación */
  301. int nuevoancho;
  302.     /* buffer para la línea escalada */
  303. char escalada[ANCHO_MAXIMO];
  304.  
  305. memset(escalada,0,ANCHO_MAXIMO);
  306.     /* si es una reducción */
  307. if(factor < 1.0)
  308.     for(i=0;i < ancho;++i)
  309.         escalada[(double)i*factor] = linea[i];
  310.     /* si es una ampliación */
  311. else
  312.     {
  313.     nuevoancho = ancho*factor;
  314.     for(i=0;i < nuevoancho;++i)
  315.         escalada[i] = linea[(double)i/factor];
  316.     }
  317.     /* devuelve línea escalada */
  318. return(escalada);
  319. }
  320.  
  321. /*---- FIN FUNCION -----------------------------------------------------------*/
  322.